package com.lm.kgmenu;

import android.content.Context;
import android.content.res.TypedArray;
import android.nfc.Tag;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.widget.HorizontalScrollView;


/**
 * Created by Xialm on 2017/6/25.
 */

public class KGSlidingMenu extends HorizontalScrollView {

    private static final String TAG = "KGSlidingMenu";
    private float mMenuRightMargin;
    private int mMenuWidth;
    private View mContentView;
    private View mMenuView;
    private boolean isMenuOpen = false;
    // 当菜单是打开的,同时点击右侧内容界面,要不要拦截事件
    private boolean isIntercept = false;


    private GestureDetector mGestureDetector;
    private GestureDetector.OnGestureListener onGestureListener =
            new GestureDetector.SimpleOnGestureListener() {
                @Override
                public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                    Log.e(TAG, "velocityX: " + velocityX); // 想左快速滑动,值为负;向右快速滑动,值为正
                    // 如果菜单打开了,且向左快速滑动,关闭菜单;向右快速滑动不做处理
                    // 如果菜单关闭了,且向右快速滑动,打开菜单;向左快速滑动不做处理
                    if (isMenuOpen) {
                        if (velocityX < 0) {
                            closeMenu();
                        }
                    } else {
                        if (velocityX > 0) {
                            openMenu();
                        }
                    }
                    return true;//super.onFling(e1, e2, velocityX, velocityY); // 默认是返回false
                }
            };

    public KGSlidingMenu(Context context) {
        this(context, null);
    }

    public KGSlidingMenu(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public KGSlidingMenu(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.KGSlidingMenu);
        mMenuRightMargin = array.getDimension(R.styleable.KGSlidingMenu_menuRightMargin, dp2px(50));

        mMenuWidth = (int) (getScreenWidth(context) - mMenuRightMargin);
        mGestureDetector = new GestureDetector(context, onGestureListener);
        array.recycle();
    }

    private float dp2px(int dp) {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());
    }

    private int getScreenWidth(Context context) {
        int screenWidth = context.getResources().getDisplayMetrics().widthPixels;
        return screenWidth;
    }

    // xln 这个方法是在布局加载完成时调用
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        ViewGroup llContainer = (ViewGroup) getChildAt(0);
        // 指定内容页的宽度为屏幕的宽度
        // 指定菜单页的宽度为 屏幕的宽度-右侧一段宽度
        mMenuView = llContainer.getChildAt(0);
        ViewGroup.LayoutParams menuParams = mMenuView.getLayoutParams();
        menuParams.width = mMenuWidth;
        // 7.0以上手机必须调用下面这句话,设置的布局参数才生效
        mMenuView.setLayoutParams(menuParams);

        mContentView = llContainer.getChildAt(1);
        ViewGroup.LayoutParams contentParams = mContentView.getLayoutParams();
        contentParams.width = getScreenWidth(getContext());
        mContentView.setLayoutParams(contentParams);
    }

    // View的绘制流程,是在Activity的onResume()之后执行的
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        // 打开界面,菜单默认是关闭的  x 是一个正值,就好比把屏幕往右x正方向移动一段距离
        scrollTo(getScreenWidth(getContext()), 0);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        isIntercept = false;
        // 如果菜单是打开的,且点击右侧内容区域:关闭菜单,同时拦截右侧内容界面的点击事件
        if (isMenuOpen) {
            float currentClickX = ev.getX();
            if (currentClickX > mMenuWidth) {
                closeMenu();
                isIntercept = true;
                // 拦截事件,同时回调用自己的onTouchEvent()方法
                return true;
            }
        }
        return super.onInterceptTouchEvent(ev);
    }

    // 手指抬起时,菜单或者内容页只能打开一个
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (isIntercept) {
            // 拦截事件 菜单打开,点击右侧内容,不走下面逻辑
            return true;
        }
        if ( mGestureDetector.onTouchEvent(ev)) {
            // 处理快速滑动
            return true;
        }


        if (ev.getAction() == MotionEvent.ACTION_UP) {
            // 根据滚动的距离来判断:如果滚动的距离大于屏幕的一半 打开菜单;反之关闭菜单
            // 很大一个值的话,关闭菜单  向右滑动一直变小到0,向左滑动0-一个大的值
            int scrollX = getScrollX();
            //Log.e(TAG, "scrollX: " + scrollX);
            if (scrollX > mMenuWidth / 2) {
                // 关闭菜单
                closeMenu();

            } else {
                // 打开菜单
                openMenu();

            }
            return true; // 满足这个条件,消费掉事件 确保super不会执行
        }
        return super.onTouchEvent(ev);
    }

    // 处理右侧内容的缩放  左侧菜单的缩放和透明度

    // 这个方法的调用时机是: 只要你调用scrollTo() 或 scrollBy()方法就会回调
    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        // Log.e(TAG, "L: " + l); // 这个left值变化范围是从: MMenuWidth --0
        // 定义一个缩放的梯度范围
        float scale = 1.0f * l / mMenuWidth; // scale 范围: 1--0

        // 设置右侧内容的缩放效果
        // 内容的缩放范围为: 1f --0.8f
        float rightScale = 0.8f + 0.2f * scale;
        // 使右边的内容进行缩放 ViewCompat类,默认缩放中心点是View的中心
        ViewCompat.setScaleX(mContentView, rightScale);
        ViewCompat.setScaleY(mContentView, rightScale);
        // 设置缩放中心点为 内容页的左侧边的中点
        ViewCompat.setPivotX(mContentView, 0);
        ViewCompat.setPivotY(mContentView, mContentView.getMeasuredHeight() / 2);


        // 设置左侧菜单的透明度和缩放动画效果
        float leftAlpha = 0.5f + (1 - scale) * 0.5f;  // 透明度0.5f - 1f
        ViewCompat.setAlpha(mMenuView, leftAlpha);
        float leftScale = 0.8f + (1 - scale) * 0.2f; // 缩放 0.7f - 1f
        ViewCompat.setScaleX(mMenuView, leftScale);
        ViewCompat.setScaleY(mMenuView, leftScale);


        // 最后一个效果,退出两个字刚开始是推着内容页进行显示的
        ViewCompat.setTranslationX(mMenuView, 0.18f * l);

        // 把上面的全部注释,只留这一行,就是一个抽屉效果;内容始终是在菜单的上面,抽屉打开时,慢慢让菜单显示出来
        //ViewCompat.setTranslationX(mMenuView, l);

        // 这种设置效果是不行的
        /*ScaleAnimation scaleAnim = new ScaleAnimation(1.0f, rightContentScale, 1.0f, rightContentScale,
                0.5f * Animation.RELATIVE_TO_SELF, 0.5f * Animation.RELATIVE_TO_SELF);
        scaleAnim.setFillAfter(true);
        mContentView.startAnimation(scaleAnim);*/

    }

    private void openMenu() {
        //scrollTo(0,0);
        smoothScrollTo(0, 0);
        isMenuOpen = true;
    }

    private void closeMenu() {
        //scrollTo(mMenuWidth,0);
        smoothScrollTo(mMenuWidth, 0);
        isMenuOpen = false;
    }
}
